﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace OrderAggregator.InputFormats.MariaRA
{
    /// <summary>
    /// МарияРА парсер заказов
    /// </summary>
    public class MariaRaFormat : BaseOrderFormat
    {
        private const string BeginTag = "(begin)";
        private const string EndTag = "(end)";

        private const string BeginKeySymbols = "(";
        private const string EndKeySymbols = "):";


        private const string DateinKey = "datein";
        private const string DateoutKey = "dateout";
        private const string TimeoutKey = "timeout";
        private const string SenderKey = "sender";
        private const string ZakazKey = "zakaz";

        public readonly static MariaRaFormat Instance = new MariaRaFormat();

        private MariaRaFormat()
        {
        }

        /// <summary>
        /// Parse
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="getStream"></param>
        /// <returns></returns>
        public override BaseOrder Parse(string filePath, Func<System.IO.Stream> getStream)
        {
            if (!string.Equals(System.IO.Path.GetExtension(filePath), dotTXT, StringComparison.InvariantCultureIgnoreCase))
            {
                return null;
            }

            var lines = ReadLines(filePath);

            //это будет признак Мария-ра формата .txt
            if (!lines.Any(ln => ln.Contains(BeginTag)))
            {
                return null;
            }

            return Parse(lines);
        }

        /// <summary>
        /// ParseAndTranslate
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public BaseOrder Parse(string[] lines)
        {
            if (lines == null || lines.Length == 0)
            {
                return null;
            }

            var order = new BaseOrder();

            int lineNum = 0;
            for (; lineNum < lines.Length; lineNum++)
            {
                var line = lines[lineNum];

                if (string.IsNullOrEmpty(line))
                {
                    continue;
                }

                line = line.Trim();

                if (string.IsNullOrEmpty(line))
                {
                    continue;
                }

                if (line == BeginTag)
                {
                    lineNum++;
                    break;
                }

                ReadHeaderLine(order, line);
            }

            var orderRowLines = new List<string>();

            for (; lineNum < lines.Length; lineNum++)
            {
                var line = lines[lineNum];

                if (line == EndTag ||
                    string.Compare(line, 0, EndTag, 0, 4) == 0) //случай подпорченного тега
                {
                    break;
                }
                
                orderRowLines.Add(line);
            }

            order.OrderRows.AddRange(orderRowLines.Select(ln => ParseOrderRow(ln)));

            return order;
        }

        private static BaseOrderRow ParseOrderRow(string orderRowLine)
        {
            var row = new BaseOrderRow();

            var columns = orderRowLine.Split('|');

            row.ProductCode = columns[1];
            row.ProductName = columns[2].Trim();
            row.UnitName = columns[3];
            row.Count = decimal.Parse(columns[4], System.Globalization.CultureInfo.InvariantCulture);
            
            return row;
        }

        private static void ReadHeaderLine(BaseOrder order, string headerLine)
        {
            string key;
            string value;

            if (!TryParseHeaderValue(headerLine, out key, out value))
            {
                return;
            }

            if (key.Equals(DateinKey))
            {
                var date = DateTime.Parse(value, RuCulture);

                order.ReceiveTime = date.Date.Add(order.ReceiveTime.TimeOfDay);
            }
            //else if (key.Equals(TimeoutKey))
            //{
            //    var vals = value.Split(':');
            //    TimeSpan time = new TimeSpan(int.ParseAndTranslate(vals[0]), int.ParseAndTranslate(vals[1]), 0);
            //    order.ReceiveTime = order.ReceiveTime.Date.Add(time);
            //}
            else if (key.Equals(SenderKey))
            {
                order.Client = value;
            }
            else if (key.Equals(ZakazKey))
            {
                order.Id = value.Substring(0, value.IndexOf("от")).Trim();
            }
        }

        private static bool TryParseHeaderValue(string text, out string key, out string value)
        {
            key = null;
            value = null;

            var startPos = text.IndexOf(BeginKeySymbols);

            if (startPos < 0)
            {
                return false;
            }

            startPos += BeginKeySymbols.Length;

            var endPos = text.IndexOf(EndKeySymbols, startPos);

            if (endPos < 0)
            {
                return false;
            }
            
            key = text.Substring(startPos, endPos - startPos);
            value = text.Substring(endPos + EndKeySymbols.Length).Trim();

            return true;
            
        }
    }
}
